package org.jeecg.modules.friends.user.controller;

/**
 * @author cold
 * @data 2024/5/20 15:50
 * @version 1.0
 */

import java.util.LinkedHashMap;
import java.util.Objects;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.ControllerMethodCheck;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.util.JwtUtil;
import org.jeecg.common.util.DySmsEnum;
import org.jeecg.common.util.DySmsHelper;
import org.jeecg.common.util.Md5Util;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.config.JeecgBaseConfig;
import org.jeecg.modules.friends.dao.ReadyToDeleteDAO;
import org.jeecg.modules.friends.model.SystemConfigDO;
import org.jeecg.modules.friends.service.SystemConfigService;
import org.jeecg.modules.friends.service.VipUserService;
import org.jeecg.modules.friends.user.entity.User;
import org.jeecg.modules.friends.user.param.PhoneLoginParam;
import org.jeecg.modules.friends.user.param.SmsMessageParam;
import org.jeecg.modules.friends.user.service.IUserService;
import org.jeecg.modules.friends.utils.RandImageUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.exceptions.ClientException;

import cn.hutool.core.util.RandomUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

/**
 * @Description: 用户信息表
 * @Author: jeecg-boot
 * @Date: 2024-05-15
 * @Version: V1.0
 */
@Slf4j
@Api(tags = "登录接口")
@RestController
@RequestMapping("/friends/loginService/")
public class UserLoginController {

    @Autowired
    private IUserService userService;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private JeecgBaseConfig jeecgBaseConfig;

    @Autowired
    private VipUserService vipUserService;

    @Autowired
    private SystemConfigService systemConfigService;
    @Autowired
    private ReadyToDeleteDAO readyToDeleteDAO;
    private final String BASE_CHECK_CODES = "qwertyuiplkjhgfdsazxcvbnmQWERTYUPLKJHGFDSAZXCVBNM1234567890";


    @PostMapping("/phoneLogin")
    @ApiOperation("验证码登录")
    @ControllerMethodCheck
    public Result<JSONObject> phoneLogin(@RequestBody PhoneLoginParam param) {
        Result<JSONObject> result = new Result<JSONObject>();
        String phone = param.getMobile();
        String smsCode = param.getCaptcha();
        String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE + phone;
        Object code = redisUtil.get(redisKey);

        if (!smsCode.equals(code)) {
            result.setMessage("手机验证码错误");
            return result;
        }
        //校验用户有效性
        User user = userService.getUserByPhone(phone);
        if (Objects.isNull(user)) {
            //注册用户
            SystemConfigDO systemConfigDO = systemConfigService.getSystemConfig();
            user = userService.registerUser(phone, param.getInviteUserId());
            Integer ticket = 0;
            if (Objects.nonNull(systemConfigDO) || systemConfigDO.getTicket() > 0) {
                ticket = systemConfigDO.getTicket();
            }
            vipUserService.addVipUser(user, 1, ticket > 0 ? ticket : 7, 7 * 24 * 3600 * 1000L);
        }

        //用户信息
        userInfo(user, result);
        try {
            readyToDeleteDAO.deleteByUserId(user.getId());
        } catch (Exception e) {
            log.error("deleteByUserId.", e);
        }
        return result;
    }

    /**
     * 后台生成图形验证码
     */
    @ApiOperation("获取验证码")
    @GetMapping(value = "/randomImage/{key}")
    @ControllerMethodCheck
    public Result<String> randomImage(HttpServletResponse response, @PathVariable("key") String key) {
        Result<String> res = new Result<String>();
        try {
            //生成验证码
            String code = RandomUtil.randomString(BASE_CHECK_CODES, 4);
            //存到redis中
            String lowerCaseCode = code.toLowerCase();

            String origin = lowerCaseCode + key + jeecgBaseConfig.getSignatureSecret();

            String realKey = Md5Util.md5Encode(origin, "utf-8");

            redisUtil.set(realKey, lowerCaseCode, 60);
            log.info("获取验证码，Redis key = {}，checkCode = {}", realKey, code);
            //返回前端
            String base64 = RandImageUtil.generate(code);
            res.setSuccess(true);
            res.setCode(200);
            res.setResult(base64);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            res.error500("获取验证码失败,请检查redis配置!");
            return res;
        }
        return res;
    }

    @PostMapping(value = "/sms")
    @ApiOperation("获取短信验证码")
    @ControllerMethodCheck
    public Result<String> sms(@RequestBody SmsMessageParam smsMessageParam) {
        Result<String> result = new Result<String>();

        //验证图形校验码
        String lowerCaseCode = smsMessageParam.getCheckCode().toLowerCase();
        String origin = lowerCaseCode + smsMessageParam.getKey() + jeecgBaseConfig.getSignatureSecret();
        String realKey = Md5Util.md5Encode(origin, "utf-8");
        if (!redisUtil.hasKey(realKey)) {
            result.error500("校验码有误");
            return result;
        } else {
            if (redisUtil.get(realKey).equals(lowerCaseCode)) {
                redisUtil.del(realKey);
                log.info("验证通过");
            } else {
                result.error500("校验码有误");
                return result;
            }
        }

        String mobile = smsMessageParam.getMobile();
        //手机号模式 登录模式: "2"  注册模式: "1"
        log.info(mobile);
        if (oConvertUtils.isEmpty(mobile)) {
            result.setMessage("手机号不允许为空！");
            result.setSuccess(false);
            return result;
        }

        String redisKey = CommonConstant.PHONE_REDIS_KEY_PRE + mobile;
        Object object = redisUtil.get(redisKey);

        if (object != null) {
            result.setMessage("验证码1分钟内，仍然有效！");
            result.setSuccess(false);
            return result;
        }

        //随机数
        String captcha = RandomUtil.randomNumbers(4);
        JSONObject obj = new JSONObject();
        obj.put("code", captcha);
        log.info("--- yzm :{}", captcha);
        try {
            boolean b = DySmsHelper.sendSms(mobile, obj, DySmsEnum.REGISTER_TEMPLATE_CODE);
            if (b == false) {
                result.setMessage("短信验证码发送失败,请稍后重试");
                result.setSuccess(false);
                return result;
            }
            redisUtil.set(redisKey, captcha, 60);
            result.setSuccess(true);
            result.setCode(200);

        } catch (ClientException e) {
            e.printStackTrace();
            result.error500(" 短信接口未配置，请联系管理员！");
            return result;
        }
        return result;
    }

    private Result<JSONObject> userInfo(User sysUser, Result<JSONObject> result) {
        // 获取用户部门信息
        JSONObject obj = new JSONObject(new LinkedHashMap<>());
        // 生成token
        String token =
                JwtUtil.signByMobile(sysUser.getMobile(), StringUtils.defaultIfBlank(sysUser.getNickname(), "-"));
        // 设置token缓存有效时间
        redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token);
        redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME * 2 / 1000);
        obj.put("token", token);
        obj.put("userInfo", sysUser);
        result.setResult(obj);
        result.success("登录成功");
        return result;
    }

    public static void main(String[] args) {
        String token = JwtUtil.signByMobile("19857105296", "西西");
        System.out.println(token);
    }
}
